<script setup lang="ts">
import { ref, onBeforeMount, computed } from 'vue'
import {
    CheckboxType,
    ColorType,
    InputNumberType,
    InputType,
    PasswordType,
    ContainerType,
    RadioType,
    RateType,
    SelectType,
    SliderType,
    SwitchType,
    TextareaType,
    TimePickerType,
    TimeSelectType,
    VirtualizedSelectType,
} from '../../types/ItemMetaTypes'
import useStore from '../../store'
import ItemResolve from './ItemsResolve.vue'
import { FormItemsEnum } from '../../store/modules/FormItems'
import { FormDataEnum } from '../../store/modules/FormData'

interface PropsType {
    preview: boolean
    formData: object
    formItem:
        | CheckboxType
        | InputType
        | PasswordType
        | TextareaType
        | InputNumberType
        | RadioType
        | RateType
        | SwitchType
        | SliderType
        | ColorType
        | SelectType
        | VirtualizedSelectType
        | TimePickerType
        | TimeSelectType
        | ContainerType
    dynamicForm: any | null
}

// eslint-disable-next-line no-undef
const props = defineProps<PropsType>()

// eslint-disable-next-line no-undef
const emit = defineEmits(['initItemData', 'deleteItem', 'copyItem', 'submit'])

const noTexts = ref(['Button', 'Container'])
const noLabels = ref(['Container'])

let storeFormItems = computed(() => useStore.state.FormItems.items)

onBeforeMount(() => {
    const key = props.formItem.modelValue
    // @ts-ignore
    if (typeof props.formData[key] === 'undefined') {
        if (props.formItem.type === 'Checkbox') {
            emit('initItemData', { key, value: [] })
        }
        if (props.formItem.type === 'InputNumber') {
            const key = props.formItem.modelValue
            emit('initItemData', { key, value: 0 })
        }
    }
    if (props.preview) {
        storeFormItems.value.forEach((e) => {
            e.selectCurrent = false
            if (e.type === 'Container') {
                // @ts-ignore
                e.cols.forEach((e1) => e1.formItems.forEach((e2: any) => (e2.selectCurrent = false)))
            }
        })
    }
})

// 触发事件删除
const deleteItem = () => {
    emit('deleteItem')
}

// 复制
const copyItem = () => {
    emit('copyItem')
}

// 点击控件时触发
const selectCurrent = (item: any): void => {
    storeFormItems.value.forEach((e) => {
        e.selectCurrent = false
        if (e.type === 'Container') {
            // @ts-ignore
            e.cols.forEach((e1) => e1.formItems.forEach((e2: any) => (e2.selectCurrent = false)))
        }
    })
    // @ts-ignore
    props.formItem.cols.forEach((e1) => e1.formItems.forEach((e2: any) => (e2.selectCurrent = false)))
    if (props.preview) {
        return
    }
    item.selectCurrent = true
    // currentItem.value = item;
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.SET_CURRENT_ITEM), item)
    // 如果是切换组件，则暂时屏蔽监听
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.RELOAD_CHANGE_ITEM))
}

// 触发事件删除
const deleteItem1 = (i: number, i1: number) => {
    // @ts-ignore
    const colItems = props.formItem.cols[i].formItems
    let key: string = colItems[i1].modelValue
    colItems.splice(i1, 1)
    // @ts-ignore
    delete props.formData[key]
    selectCurrent({})
}

// 触发事件复制
const copyItem1 = (i: number, i1: number) => {
    // @ts-ignore
    const colItems = props.formItem.cols[i].formItems
    let formItem = JSON.parse(JSON.stringify(colItems[i1]))
    // @ts-ignore
    colItems.forEach((e) => (e.selectCurrent = false))
    formItem.modelValue = formItem.type + '_' + new Date().getTime()
    colItems.splice(i1 + 1, 0, formItem)
    if (formItem.type === 'Checkbox') {
        // @ts-ignore
        // eslint-disable-next-line vue/no-mutating-props
        props.formData[formItem.modelValue] = []
    }
    if (formItem.type === 'InputNumber') {
        // @ts-ignore
        // eslint-disable-next-line vue/no-mutating-props
        props.formData[formItem.modelValue] = 0
    }
}

// 初始化表单的特殊字段双向绑定属性
const initItemData1 = (e: any): void => {
    // @ts-ignore
    // eslint-disable-next-line vue/no-mutating-props
    props.formData[e.key] = e.value
    if (!e.key) {
        return
    }
    // 移除原先存在的key
    let keys: Array<string> = e.key.split('_')
    if (!keys || keys.length !== 2) {
        return
    }
    // @ts-ignore
    delete props.formData[keys[0]]
}

// 添加时触发
const onAdd = (original: any): void => {
    let { newIndex, target } = original
    if (!(target && target.id)) {
        return
    }
    const colIndex = parseInt(target.id.replaceAll('container-draggable', ''))
    // @ts-ignore
    const colItems = props.formItem.cols[colIndex].formItems
    if (newIndex === colItems.length) {
        // 加在最后边的情况下需要-1
        newIndex -= 1
    }
    let item = colItems[newIndex]
    let keyPrev = item.modelValue
    const key = item.modelValue + '_' + new Date().getTime()
    colItems[newIndex] = JSON.parse(JSON.stringify(item))
    colItems[newIndex].modelValue = key
    // @ts-ignore
    delete props.formData[keyPrev]
}

// 重置
const reset = (): void => {
    if (props.dynamicForm) {
        props.dynamicForm.resetFields()
    }
    // 使用表单的resetFields方法后，表单双向绑定的对象中会出现表单内所有有modelValue的组件的modelValue值
    storeFormItems.value.forEach((e) => {
        if (e.type === 'Button' || e.type === 'Container') {
            useStore.dispatch(FormDataEnum.ModuleFunctionName(FormDataEnum.REMOVE_FORM_DATA), e.modelValue)
        }
    })
}

// 提交
const submit = (): void => {
    emit('submit')
}

/* eslint-disable */
// 实在改不动了，先禁用吧
</script>

<template>
    <el-form-item
        :class="[
            formItem.type === 'Container' ? 'container-item' : '',
            formItem.type === 'Container' && preview ? 'container-item' : formItem.type,
            preview ? '' : 'edit',
            formItem.selectCurrent ? 'active' : '',
            formItem.label ? '' : 'no-text',
            formItem.labelWidth <= 10 ? 'hide-text' : '',
        ]"
        :label="noTexts.includes(formItem.type) ? '' : formItem.label"
        :label-width="formItem.labelWidth"
        :prop="formItem.modelValue"
        v-bind="{ rules: formItem.rules }"
    >
        <!-- 输入框 -->
        <el-input v-if="formItem.type === 'Input'" v-bind="formItem.props" v-model="formData[formItem.modelValue]" />
        <!-- 文本域 -->
        <el-input
            v-if="formItem.type === 'Textarea'"
            type="textarea"
            v-bind="formItem.props"
            v-model="formData[formItem.modelValue]"
        />
        <!-- 密码框 -->
        <el-input
            v-if="formItem.type === 'Password'"
            type="password"
            v-bind="formItem.props"
            v-model="formData[formItem.modelValue]"
        />
        <!-- 复选框 -->
        <el-checkbox-group
            v-if="formItem.type === 'Checkbox'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        >
            <el-checkbox
                v-for="option in formItem.options"
                :label="option.value"
                :border="formItem.props.border"
                :disabled="formItem.props.disabled"
            >
                {{ option.label }}
            </el-checkbox>
        </el-checkbox-group>
        <!-- 步进器 -->
        <el-input-number
            v-if="formItem.type === 'InputNumber'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <!-- 单选框 -->
        <el-radio-group
            v-if="formItem.type === 'Radio'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        >
            <el-radio
                v-for="option in formItem.options"
                :label="option.value"
                :border="formItem.props.border"
                :disabled="formItem.props.disabled"
            >
                {{ option.label }}
            </el-radio>
        </el-radio-group>
        <!-- 评分 -->
        <el-rate v-if="formItem.type === 'Rate'" v-model="formData[formItem.modelValue]" v-bind="formItem.props" />
        <!-- 开关 -->
        <el-switch v-if="formItem.type === 'Switch'" v-model="formData[formItem.modelValue]" v-bind="formItem.props" />
        <!-- 滑块 -->
        <el-slider v-if="formItem.type === 'Slider'" v-model="formData[formItem.modelValue]" v-bind="formItem.props" />
        <!-- 下拉选择器 -->
        <el-select v-if="formItem.type === 'Select'" v-model="formData[formItem.modelValue]" v-bind="formItem.props">
            <el-option v-for="item in formItem.options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <!-- 虚拟选择器 -->
        <el-select-v2
            v-if="formItem.type === 'VirtualizedSelect'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <!-- 颜色选择器 -->
        <el-color-picker
            v-if="formItem.type === 'Color'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <!-- 时间选择器 -->
        <el-time-picker
            v-if="formItem.type === 'TimePicker' || formItem.type === 'TimePickerRange'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <!-- 时间下拉 -->
        <el-time-select
            v-if="formItem.type === 'TimeSelect'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <!-- 日期时间选择器 暂时有问题 -->
        <el-date-picker
            v-if="formItem.type === 'DatetimePicker'"
            v-model="formData[formItem.modelValue]"
            v-bind="formItem.props"
        />
        <el-button v-if="formItem.type === 'Button' && formItem.buttonType === 'reset'" v-bind="formItem.props" @click="reset">
            {{ formItem.label }}
        </el-button>
        <el-button v-if="formItem.type === 'Button' && formItem.buttonType === 'submit'" v-bind="formItem.props" @click="submit">
            {{ formItem.label }}
        </el-button>
        <el-row v-if="formItem.type === 'Container'" v-bind="formItem.props">
            <el-col v-for="(item, i) in formItem.cols" v-bind="item.props">
                <draggable
                    :list="item.formItems"
                    group="people"
                    class="container-draggable"
                    :id="'container-draggable' + i"
                    :disabled="preview"
                    :animation="300"
                    @add="onAdd"
                >
                    <ItemResolve
                        v-for="(item1, i1) in item.formItems"
                        :formItem="item1"
                        :preview="preview"
                        :formData="formData"
                        :key="item1.modelValue"
                        :dynamicForm="dynamicForm"
                        @copyItem="copyItem1(i, i1)"
                        @click.stop="selectCurrent(item1)"
                        @deleteItem="deleteItem1(i, i1)"
                        @initItemData="initItemData1"
                    />
                </draggable>
            </el-col>
        </el-row>
        <el-icon :size="17" color="red" class="item-icon" v-if="formItem.selectCurrent" @click.stop="deleteItem">
            <delete />
        </el-icon>
        <el-icon
            :size="17"
            color="var(--el-color-primary)"
            class="item-icon item-icon-copy"
            v-if="formItem.selectCurrent"
            @click.stop="copyItem"
        >
            <copy-document />
        </el-icon>
    </el-form-item>
</template>

<style scoped>
.hide-text ::v-deep(.el-form-item__label:first-line) {
    display: none;
}
.container-item {
    width: 99%;
}
.Container {
    min-height: 20px;
    padding: 20px 0 !important;
    border: 1px dashed var(--el-border-color-base) !important;
}

.Container .el-col {
    border: 1px dashed var(--el-border-color-base) !important;
}

.container-draggable {
    width: 100%;
    height: 100%;
    min-height: 50px;
}

.el-form-item .el-form-item {
    margin-bottom: 22px;
}

.no-text .el-button ::v-deep([class*='el-icon'] + span) {
    margin-left: 0;
}
/*.no-label ::v-deep(.el-row) {
    margin-left: 0 !important;
}*/
.edit {
    padding: 20px 10px;
    align-items: center;
    border: 1px dashed transparent;
}

.Container .item-icon {
    top: 103%;
}

.item-icon {
    position: absolute;
    top: 109%;
    right: 30px;
}

.item-icon-copy {
    right: 10px;
}

.item-icon:hover {
    cursor: pointer;
}

.active {
    border: 1px dashed var(--el-color-primary) !important;
}

.el-slider {
    padding: 0 11px;
}
.el-radio-group,
.el-checkbox-group,
.Color ::v-deep(.el-form-item__content),
.Rate ::v-deep(.el-form-item__content) {
    display: flex;
    align-items: center;
}
</style>
